package com.lagou.factory;


import com.lagou.anno.Autowired;
import com.lagou.anno.Component;
import com.lagou.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理类实现事务管理的横切逻辑代码
 */
@Component
public class ProxyFactory {

    @Autowired
    private TransactionManager transactionManager;


    public Object getProxy(Object obj){
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object invoke = null;
                try {
                    //1.开启事务
                    transactionManager.beginTransaction();
                    //2.调用service的方法
                    invoke = method.invoke(obj, args);
                    //3.提交事务
                    transactionManager.commitTransction();
                } catch (Exception e) {
                    //4.异常后回滚事务
                    transactionManager.rollbackTransction();
                    throw e.getCause();
                }
                return invoke;
            }
        });
    }

    /**
     * cglib动态代理获取代理对象，管理service的事务
     * @param target  被代理的对象
     * @return  已经实现横切逻辑的代理对象
     */
    public Object getCglibProxy(Object target){
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(target.getClass());
         enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Object invoke = null;
                try {
                    //1.开启事务
                    transactionManager.beginTransaction();
                    //2.调用service的方法
                    invoke = method.invoke(target, objects);
                    //3.提交事务
                    transactionManager.commitTransction();
                } catch (Exception e) {
                    //4.异常后回滚事务
                    transactionManager.rollbackTransction();
                    throw e.getCause();
                }
                return invoke;
            }
        });
        return enhancer.create();
    }



}
